<template>
    <view class="uni-indexed-list" ref="list" id="list">
        <!-- #ifdef APP-NVUE -->
        <list class="uni-indexed-list__scroll" scrollable="true" show-scrollbar="false">
            <cell v-for="(list, idx) in lists" :key="idx" :ref="'uni-indexed-list-' + idx">
                <!-- #endif -->
                <!-- #ifndef APP-NVUE -->
                <scroll-view :scroll-into-view="scrollViewId" class="uni-indexed-list__scroll" scroll-y>
                    <view v-for="(list, idx) in lists" :key="idx" :id="'uni-indexed-list-' + idx">
                        <!-- #endif -->
                        <indexed-list-item :list="list" :loaded="loaded" :idx="idx" :showSelect="showSelect"
                                           @itemClick="onClick"></indexed-list-item>
                        <!-- #ifndef APP-NVUE -->
                    </view>
                </scroll-view>
                <!-- #endif -->
                <!-- #ifdef APP-NVUE -->
            </cell>
        </list>
        <!-- #endif -->
        <view class="uni-indexed-list__menu" @touchstart="touchStart" @touchmove.stop.prevent="touchMove"
              @touchend="touchEnd" @mousedown.stop="mousedown" @mousemove.stop.prevent="mousemove"
              @mouseleave.stop="mouseleave">
            <view v-for="(list, key) in lists" :key="key" class="uni-indexed-list__menu-item"
                  :class="touchmoveIndex == key ? 'uni-indexed-list__menu--active' : ''">
                <text class="uni-indexed-list__menu-text"
                      :class="touchmoveIndex == key ? 'uni-indexed-list__menu-text--active' : ''">{{ list.key }}
                </text>
            </view>
        </view>
        <view v-if="touchmove" class="uni-indexed-list__alert-wrapper">
            <text class="uni-indexed-list__alert">{{ lists[touchmoveIndex].key }}</text>
        </view>
    </view>
</template>
<script>
    import indexedListItem from './uni-indexed-list-item.vue'
    // #ifdef APP-NVUE
    const dom = weex.requireModule('dom');
    // #endif
    // #ifdef APP-PLUS
    function throttle(func, delay) {
        var prev = Date.now();
        return function () {
            var context = this;
            var args = arguments;
            var now = Date.now();
            if (now - prev >= delay) {
                func.apply(context, args);
                prev = Date.now();
            }
        }
    }

    function touchMove(e) {
        let pageY = e.touches[0].pageY
        let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
        if (this.touchmoveIndex === index) {
            return false
        }
        let item = this.lists[index]
        if (item) {
            // #ifndef APP-NVUE
            this.scrollViewId = 'uni-indexed-list-' + index
            this.touchmoveIndex = index
            // #endif
            // #ifdef APP-NVUE
            dom.scrollToElement(this.$refs['uni-indexed-list-' + index][0], {
                animated: false
            })
            this.touchmoveIndex = index
            // #endif
        }
    }

    const throttleTouchMove = throttle(touchMove, 40)
    // #endif

    /**
     * IndexedList 索引列表
     * @description 用于展示索引列表
     * @tutorial https://ext.dcloud.net.cn/plugin?id=375
     * @property {Boolean} showSelect = [true|false] 展示模式
     *    @value true 展示模式
     *    @value false 选择模式
     * @property {Object} options 索引列表需要的数据对象
     * @event {Function} click 点击列表事件 ，返回当前选择项的事件对象
     * @example <uni-indexed-list options="" showSelect="false" @click=""></uni-indexed-list>
     */
    export default {
        name: 'UniIndexedList',
        components: {
            indexedListItem
        },
        emits: ['click'],
        props: {
            options: {
                type: Array,
                default() {
                    return []
                }
            },
            showSelect: {
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                lists: [],
                winHeight: 0,
                itemHeight: 0,
                winOffsetY: 0,
                touchmove: false,
                touchmoveIndex: -1,
                scrollViewId: '',
                touchmovable: true,
                loaded: false,
                isPC: false
            }
        },
        watch: {
            options: {
                handler: function () {
                    this.setList()
                },
                deep: true
            }
        },
        mounted() {
            // #ifdef H5
            this.isPC = this.IsPC()
            // #endif
            setTimeout(() => {
                this.setList()
            }, 50)
            setTimeout(() => {
                this.loaded = true
            }, 300);
        },
        methods: {
            setList() {
                let index = 0;
                this.lists = []
                this.options.forEach((value, index) => {
                    if (value.data.length === 0) {
                        return
                    }
                    let indexBefore = index
                    let items = value.data.map(item => {
                        let obj = {}
                        obj['key'] = value.letter
                        obj['name'] = item
                        obj['itemIndex'] = index
                        index++
                        obj.checked = item.checked ? item.checked : false
                        return obj
                    })
                    this.lists.push({
                        title: value.letter,
                        key: value.letter,
                        items: items,
                        itemIndex: indexBefore
                    })
                })
                // #ifndef APP-NVUE
                uni.createSelectorQuery()
                    .in(this)
                    .select('#list')
                    .boundingClientRect()
                    .exec(ret => {
                        this.winOffsetY = ret[0].top
                        this.winHeight = ret[0].height
                        this.itemHeight = this.winHeight / this.lists.length
                    })
                // #endif
                // #ifdef APP-NVUE
                dom.getComponentRect(this.$refs['list'], (res) => {
                    this.winOffsetY = res.size.top
                    this.winHeight = res.size.height
                    this.itemHeight = this.winHeight / this.lists.length
                })
                // #endif
            },
            touchStart(e) {
                this.touchmove = true
                let pageY = this.isPC ? e.pageY : e.touches[0].pageY
                let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
                let item = this.lists[index]
                if (item) {
                    this.scrollViewId = 'uni-indexed-list-' + index
                    this.touchmoveIndex = index
                    // #ifdef APP-NVUE
                    dom.scrollToElement(this.$refs['uni-indexed-list-' + index][0], {
                        animated: false
                    })
                    // #endif
                }
            },
            touchMove(e) {
                // #ifndef APP-PLUS
                let pageY = this.isPC ? e.pageY : e.touches[0].pageY
                let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
                if (this.touchmoveIndex === index) {
                    return false
                }
                let item = this.lists[index]
                if (item) {
                    this.scrollViewId = 'uni-indexed-list-' + index
                    this.touchmoveIndex = index
                }
                // #endif
                // #ifdef APP-PLUS
                throttleTouchMove.call(this, e)
                // #endif
            },
            touchEnd() {
                this.touchmove = false
                // this.touchmoveIndex = -1
            },

            /**
             * 兼容 PC @tian
             */

            mousedown(e) {
                if (!this.isPC) return
                this.touchStart(e)
            },
            mousemove(e) {
                if (!this.isPC) return
                this.touchMove(e)
            },
            mouseleave(e) {
                if (!this.isPC) return
                this.touchEnd(e)
            },

            // #ifdef H5
            IsPC() {
                var userAgentInfo = navigator.userAgent;
                var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
                var flag = true;
                for (let v = 0; v < Agents.length - 1; v++) {
                    if (userAgentInfo.indexOf(Agents[v]) > 0) {
                        flag = false;
                        break;
                    }
                }
                return flag;
            },
            // #endif


            onClick(e) {
                let {
                    idx,
                    index
                } = e
                let obj = {}
                for (let key in this.lists[idx].items[index]) {
                    obj[key] = this.lists[idx].items[index][key]
                }
                let select = []
                if (this.showSelect) {
                    this.lists[idx].items[index].checked = !this.lists[idx].items[index].checked
                    this.lists.forEach((value, idx) => {
                        value.items.forEach((item, index) => {
                            if (item.checked) {
                                let obj = {}
                                for (let key in this.lists[idx].items[index]) {
                                    obj[key] = this.lists[idx].items[index][key]
                                }
                                select.push(obj)
                            }
                        })
                    })
                }
                this.$emit('click', {
                    item: obj,
                    select: select
                })
            }
        }
    }
</script>
<style lang="scss">
    .uni-indexed-list {
        position: absolute;
        left: 0;
        top: 0;
        right: 0;
        bottom: 0;
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: row;
    }

    .uni-indexed-list__scroll {
        flex: 1;
    }

    .uni-indexed-list__menu {
        width: 24px;
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: column;
    }

    .uni-indexed-list__menu-item {
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex: 1;
        align-items: center;
        justify-content: center;
        /* #ifdef H5 */
        cursor: pointer;
        /* #endif */
    }

    .uni-indexed-list__menu-text {
        font-size: 12px;
        text-align: center;
        color: #aaa;
    }

    .uni-indexed-list__menu--active {
        // background-color: rgb(200, 200, 200);
    }

    .uni-indexed-list__menu--active {
    }

    .uni-indexed-list__menu-text--active {
        border-radius: 16px;
        width: 16px;
        height: 16px;
        line-height: 16px;
        background-color: #007aff;
        color: #fff;
    }

    .uni-indexed-list__alert-wrapper {
        position: absolute;
        left: 0;
        top: 0;
        right: 0;
        bottom: 0;
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: row;
        align-items: center;
        justify-content: center;
    }

    .uni-indexed-list__alert {
        width: 80px;
        height: 80px;
        border-radius: 80px;
        text-align: center;
        line-height: 80px;
        font-size: 35px;
        color: #fff;
        background-color: rgba(0, 0, 0, 0.5);
    }
</style>
